<!DOCTYPE HTML>
<html lang="zh" xml:th="http://www.thymeleaf.org">
<head>
    <title th:text="${pageName}">物联网设备调试</title>
    <link rel="stylesheet" th:href="@{/statics/bootstrap/4.6.0/bootstrap.min.css}" />
    <script th:src="@{/statics/jquery-1.12.4.min.js}"></script>
    <script th:src="@{/statics/bootstrap/4.6.0/bootstrap.min.js}"></script>
    <script th:src="@{/statics/system/common.js}"></script>
    <link rel="stylesheet" th:href="@{/statics/layui/layui.css}" />
    <script th:src="@{/statics/layui/layui.js}"></script>
    <script th:src="@{/statics/dayjs.min.js}"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
</head>

<body>
<div class="container">
    <h3 th:text="${pageName}" class="title">物联网设备调试</h3>
    <div class="alert alert-info" style="margin-bottom: 4px;padding: 3px 10px;">
        <span th:text="${serverInfo}"></span>
        <div class="d-flex flex-row flex-md-row justify-content-start justify-content-md-end w-100">
            <button onclick="reConnect()" class="btn btn-primary btn-sm mx-1 my-1">修改订阅</button>
            <button onclick="exportTxT()" class="btn btn-primary btn-sm mx-1 my-1">导出日志</button>
            <button onclick="clearLog()" class="btn btn-primary btn-sm mx-1 my-1">清空日志</button>
            <button onclick="closeWebSocket()" class="btn btn-danger btn-sm mx-1 my-1">关闭连接</button>
        </div>
    </div>



    <input type="hidden" name="token" id="token" th:value="${token}">
    <input type="hidden" name="token" id="id" th:value="${pageId}">
    <div class="row mb-2 mt-2">
        <div class="col-md-6 d-flex align-items-center mb-1">
            <label for="sendTopic" class="mr-2 mb-0">发送Topic</label>
            <div class="input-group">
                <input id="sendTopic" type="text" class="form-control" th:value="${sendTopic}" />
                <div class="input-group-append">
                    <button th:if="${login}" style="display: none;" onclick="saveTopic('sendTopic')" class="btn btn-success save-btn-topic" type="button">保存</button>
                </div>
            </div>
        </div>
        <div class="col-md-6 d-flex align-items-center mb-1">
            <label for="receiveTopic" class="mr-2 mb-0">接收Topic</label>
            <div class="input-group">
                <input id="receiveTopic" type="text" class="form-control" th:value="${receiveTopic}" />
                <div class="input-group-append">
                    <button th:if="${login}" style="display: none;" onclick="saveTopic('receiveTopic')" class="btn btn-success save-btn-topic" type="button">保存</button>
                </div>
            </div>
        </div>
    </div>




    <div class="form-group" hidden="hidden">
        <label for="qos">QoS</label>
        <input id="qos" min="0" max="2" type="number" class="form-control" th:value="${qos}" />
    </div>

    <div id="table" th:style="${params.size() > 0} ? '' : 'display: none;'">
        <table class="table">
            <tbody>
            <tr th:each="p : ${params}" th:id="${p.id}">
                <td>
                    <div class="input-group">
                        <textarea wrap="off" name="message1" class="form-control" style="resize: none; overflow: scroll; display: none;" th:text="${p.message}"></textarea>
                        <input name="messageInput" type="text" class="form-control" th:value="${p.message}" />
                        <div class="input-group-append">
                            <button th:if="${login}" style="display: none;min-height: 36px;" onclick="saveMessage(this)" class="btn btn-success save-btn" type="button">保存</button>
                        </div>
                    </div>
                </td>
                <td style="width: 140px">
                    <button style="min-height: 36px;width: 140px" onclick="sendOther(this)" class="btn btn-primary" type="button" th:text="${p.button}"></button>
                </td>
            </tr>
            </tbody>
        </table>
    </div>
    <div class="input-group mb-3">
        <input id="text" type="text" class="form-control" placeholder="请输入调试信息">
        <div class="input-group-append">
            <button onclick="send()" class="btn btn-primary">发送</button>
        </div>
    </div>
    <textarea wrap="off" id="message" class="form-control" disabled style="height: 500px;"></textarea>
</div>
</body>

<script type="text/javascript">
    let websocket;

    function initialize() {
        const token = $('#token').val();
        const sendTopic = $('#sendTopic').val();
        const receiveTopic = $('#receiveTopic').val();
        const qos = $('#qos').val();

        const sendTopicBase64 = base64encode(sendTopic);
        const receiveTopicBase64 = base64encode(receiveTopic);

        if ('WebSocket' in window) {
            const url = `${getNmqsWebsocket()}/websocket/${token}/${sendTopicBase64}/${receiveTopicBase64}/${qos}`;
            console.log(url);
            initializeWebSocket(url);
        } else {
            alert('您的浏览器不支持WebSocket协议，建议您更换 Chrome 浏览器');
        }

        setupMessageToggles();
    }

    function initializeWebSocket(url) {
        displayMessage("正在连接到远程服务器...");
        websocket = new WebSocket(url);

        websocket.onerror = () => displayMessage("连接失败，请检查服务器是否正常！");
        websocket.onopen = () => displayMessage("开始建立连接");
        websocket.onmessage = event => displayMessage(event.data, "Receive");
        websocket.onclose = () => displayMessage("连接关闭");

        window.onbeforeunload = () => websocket.close();
    }

    function displayMessage(message, type = "System") {
        const prefix = `[${type}][${dayjs().format('HH:mm:ss')}] `;
        setMessageInnerHTML(prefix + message);
    }

    function validateInput(selector, errorMessage) {
        const value = $(selector).val();
        if (!value) {
            alert(errorMessage);
            return false;
        }
        return value;
    }

    function reConnect() {
        const token = validateInput('#token', "Token不能为空！");
        const sendTopic = validateInput('#sendTopic', "发送订阅不能为空！");
        const receiveTopic = validateInput('#receiveTopic', "接收订阅不能为空！");
        const qos = validateInput('#qos', "QoS不正确");

        if (qos < 0 || qos > 2) {
            alert("QoS不正确");
            return;
        }

        if (!sendTopic || !receiveTopic || qos === false) return;

        closeWebSocket();

        setTimeout(() => {
            const sendTopicBase64 = base64encode(sendTopic);
            const receiveTopicBase64 = base64encode(receiveTopic);
            const url = `${getNmqsWebsocket()}/websocket/${token}/${sendTopicBase64}/${receiveTopicBase64}/${qos}`;

            console.log(url);
            initializeWebSocket(url);
        }, 1000);
    }

    function setMessageInnerHTML(innerHTML) {
        const message = $('#message').val();
        const messageArray = message.split('\n');
        if (messageArray.length > 500) {
            messageArray.pop();
        }
        messageArray.unshift(innerHTML);
        $('#message').val(messageArray.join('\n'));
    }

    function closeWebSocket() {
        displayMessage("正在关闭连接...");
        if (websocket) websocket.close();
    }

    function send() {
        const message = $('#text').val();
        if (websocket && message) {
            websocket.send(message);
            displayMessage(message, "Send");
        }
    }

    function setupInputListeners() {
        const inputs = document.getElementsByName('messageInput');
        const sendTopicInput = document.getElementById('sendTopic');
        const receiveTopicInput = document.getElementById('receiveTopic');

        inputs.forEach(input => {
            const textarea = input.previousElementSibling;
            const saveButton = input.nextElementSibling.querySelector('.save-btn');

            input.dataset.initialValue = input.value;

            input.addEventListener('input', function() {
                if (textarea.value.split('\n').length === 1 && this.value !== this.dataset.initialValue) {
                    saveButton.style.display = 'inline-block';
                } else {
                    saveButton.style.display = 'none';
                }
            });
        });

        // 监听发送Topic
        if (sendTopicInput) {
            const sendSaveButton = sendTopicInput.nextElementSibling.querySelector('.save-btn-topic');
            sendTopicInput.dataset.initialValue = sendTopicInput.value;

            sendTopicInput.addEventListener('input', function() {
                sendSaveButton.style.display = (this.value !== this.dataset.initialValue) ? 'inline-block' : 'none';
            });
        }

        // 监听接收Topic
        if (receiveTopicInput) {
            const receiveSaveButton = receiveTopicInput.nextElementSibling.querySelector('.save-btn-topic');
            receiveTopicInput.dataset.initialValue = receiveTopicInput.value;

            receiveTopicInput.addEventListener('input', function() {
                receiveSaveButton.style.display = (this.value !== this.dataset.initialValue) ? 'inline-block' : 'none';
            });
        }
    }

    function saveTopic(topicType) {
        const input = document.getElementById(topicType);
        const newValue = input.value;

        const id = $('#id').val();

        if (!newValue) {
            layer.msg("Topic不能为空");
            return;
        }

        let json
        if (topicType == 'sendTopic') {
            json = JSON.stringify({
                id: id,
                sendTopic: newValue
            });
        } else if (topicType == 'receiveTopic') {
            json = JSON.stringify({
                id: id,
                receiveTopic: newValue
            });
        }

        $.ajax({
            url: `/page/updateTopic`,
            type: 'POST',
            contentType: 'application/json',
            data: json,
            success: function (data) {
                if (data.code === 200) {
                    layer.msg("保存成功");
                    input.dataset.initialValue = newValue;
                    input.nextElementSibling.querySelector('.save-btn-topic').style.display = 'none';
                } else {
                    layer.msg("保存失败");
                }
            },
            error: function (error) {
                console.error("保存Topic时发生错误:", error);
                layer.msg("保存失败");
            }
        });
    }

    function saveMessage(button) {
        const container = button.parentElement.parentElement;
        const input = container.querySelector('input');
        const textarea = container.querySelector('textarea');
        const message = input.value.trim() || textarea.value.trim();
        const rowId = container.closest('tr').id;

        console.log("保存的消息:", message, "行ID:", rowId);

        // 保存消息
        $.ajax({
            url: '/page/param/update',
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify({
                id: rowId,
                message: message
            }),
            success: function (data) {
                if (data.code === 200) {
                    layer.msg("保存成功");
                    input.dataset.initialValue = message;
                    button.style.display = 'none';
                } else {
                    layer.msg("保存失败");
                }
            },
            error: function (error) {
                console.error("保存消息时发生错误:", error);
                layer.msg("保存失败");
            }
        });

        button.style.display = 'none';
    }

    document.addEventListener('DOMContentLoaded', function() {
        initialize();
        setupInputListeners();
    });


    function sendOther(this1) {
        let parentRow = $(this1).closest('tr');
        let textarea = parentRow.find('textarea');
        let input = parentRow.find('input');

        let textareaContent = textarea.val().trim();
        let inputContent = input.val().trim();

        // 判断是否为批量命令
        if (textareaContent.includes('\n')) {
            // 批量发送
            let messageArray = textareaContent.split('\n');
            let i = 0;
            let interval = setInterval(function () {
                if (i < messageArray.length) {
                    try {
                        websocket.send(messageArray[i]);
                        displayMessage(messageArray[i], "Send");
                        i++;
                    } catch (error) {
                        console.error("发送消息时发生错误:", error);
                        clearInterval(interval);
                    }
                } else {
                    clearInterval(interval);
                }
            }, 500);
        } else if (inputContent) {
            // 发送单个命令
            try {
                websocket.send(inputContent);
                displayMessage(inputContent, "Send");
            } catch (error) {
                console.error("发送消息时发生错误:", error);
            }
        }
    }

    function base64encode(text) {
        return btoa(text).replace(/\//g, "_");
    }

    function setupMessageToggles() {
        const messages = document.getElementsByName('message1');
        const messageInputs = document.getElementsByName('messageInput');

        messages.forEach((message, i) => {
            const lines = message.value.split('\n');
            const saveButton = messageInputs[i].nextElementSibling.querySelector('.save-btn');

            if (lines.length > 1) {
                message.style.display = 'none';
                messageInputs[i].value = lines[0];

                const button = document.createElement('button');
                button.type = 'button';
                button.textContent = '展开';
                button.style.marginLeft = '10px';
                button.classList.add('btn', 'btn-primary');
                button.onclick = () => toggleView(button);

                messageInputs[i].parentElement.appendChild(button);
                saveButton.style.display = 'none'; // 隐藏保存按钮
            } else {
                message.style.display = 'none';
            }
        });
    }

    function toggleView(button) {
        const container = button.parentElement;
        const textarea = container.querySelector('textarea');
        const input = container.querySelector('input');

        const isHidden = textarea.style.display === 'none';

        if (isHidden) {
            // 展开 textarea
            textarea.style.display = 'block';
            input.style.display = 'none';
            // 将 textarea 的内容更新为 input 的内容
            const firstLine = input.value;
            textarea.value = firstLine + '\n' + textarea.value.split('\n').slice(1).join('\n');
        } else {
            // 折叠 textarea，将 input 设置为 textarea 的第一行内容
            textarea.style.display = 'none';
            input.style.display = 'block';
            const firstLine = textarea.value.split('\n')[0];
            input.value = firstLine;
        }

        button.textContent = isHidden ? '收起' : '展开';
    }


    function exportTxT() {
        const message = $('#message').val();
        const blob = new Blob([message], { type: "text/plain;charset=utf-8" });
        saveAs(blob, `mqtt-${dayjs().format('YYYY-MM-DD-HH-mm-ss')}.txt`);
    }

    function clearLog() {
        $('#message').val('');
    }

    function saveAs(blob, filename) {
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        a.click();
        window.URL.revokeObjectURL(url);
    }
</script>

<style>
    html, body {
        margin: 0;
        height: 100%;
    }

    .container {
        max-width: 700px; /* 默认最大宽度 */
        margin: 0 auto;
        padding: 10px;
        display: flex;
        flex-direction: column;
        box-sizing: border-box;
    }

    @media (max-width: 768px) {
        .container {
            max-width: none; /* 移动设备上不限制宽度 */
        }
    }

    #table {

    }

    #table td {
        padding: 2px 1px;
    }

    .table td, .table th {
        border: none;
    }

    textarea {
        width: 100%;
        resize: none;
        height: auto;
        overflow: hidden;
        background-color: #f8f9fa;
        overflow-x: scroll;
    }

    .input-group {
        display: flex;
        align-items: center;
        width: auto;
    }

    #message {
        margin-bottom: 10px;
        height: 500px;
        overflow: scroll;
        font-size: 14px;
    }

    .alert {
        padding: 10px 15px;
        display: flex;
        flex-direction: column; /* 默认垂直排列 */
        align-items: flex-start; /* 左对齐内容 */
        border-radius: .25rem;
    }

    @media (min-width: 768px) {
        .alert {
            flex-direction: row; /* 中等及以上屏幕水平排列 */
            align-items: center; /* 垂直居中 */
        }
    }

    .alert span {
        color: #666;
        font-size: 16px;
    }

    .form-control {
        font-size: 14px;
    }

    .save-btn {
        margin-left: 5px;
    }


    .input-group {
        display: flex;
        align-items: center;
    }

    .input-group-append {
        margin-left: 5px;
    }

    .save-btn-topic {
        display: none;
    }

    .btn-success {
        background-color: #28a745;
        border-color: #28a745;
    }

    .btn-success:hover {
        background-color: #218838;
        border-color: #1e7e34;
    }

</style>


</html>
